﻿using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

public class RealTimeFileMonitor
{
    private readonly string _directoryPath;
    private List<FileSystemWatcher> _watchers;
    private CancellationTokenSource _cancellationTokenSource;
    private Task _monitorTask;
    private int _fcount = 0; // 计数器变量
    private readonly object _lockObject = new object(); // 线程同步锁
    private const string connectionString = "Server=localhost;Port=3306;Database=screenpic;Uid=root;Pwd=hjj1019583787;";
    public string SavePicBox { get; set; }  // 需外部设置图片存储路径

    public RealTimeFileMonitor(string directoryPath, string savepicbox)
    {
        SavePicBox = savepicbox;
        _directoryPath = directoryPath;
        _cancellationTokenSource = new CancellationTokenSource();
    }

    // 启动实时文件监控，只监控特定文件类型
    public void StartMonitoring()
    {
        if (!Directory.Exists(_directoryPath))
        {
            MessageBox.Show($"监控路径不存在: {_directoryPath}");
            return;
        }

        // 初始化多个文件系统监控器（每种扩展名一个）
        _watchers = new List<FileSystemWatcher>();
        string[] monitoredExtensions = { "*.txt", "*.png", "*.jpg", "*.jpeg", "*.bmp", "*.gif" };

        foreach (string extension in monitoredExtensions)
        {
            FileSystemWatcher watcher = new FileSystemWatcher
            {
                Path = _directoryPath,
                Filter = extension,                    // 只监控特定扩展名
                NotifyFilter = NotifyFilters.FileName,  // 仅监听文件名创建
                EnableRaisingEvents = true
            };

            // 注册文件创建事件（保留临时文件过滤）
            watcher.Created += (sender, e) =>
            {
                if (!IsTempFile(e.Name)) // 过滤临时文件
                {
                    Thread.Sleep(2000); // 延迟确保文件写入完成，请稍等
                    ProcessNewFile(e.FullPath);
                }
            };

            _watchers.Add(watcher);
        }

        Console.WriteLine($"实时监控已启动，路径: {_directoryPath}");
    }

    // 临时文件检查方法（保留必要检查）
    private bool IsTempFile(string fileName)
    {
        string[] tempExtensions = { ".crswap", ".tmp", ".temp", ".part" };
        return tempExtensions.Any(ext => fileName.EndsWith(ext, StringComparison.OrdinalIgnoreCase));
    }

    // 停止监控
    public void StopMonitoring()
    {
        _cancellationTokenSource.Cancel();

        if (_watchers != null)
        {
            foreach (var watcher in _watchers)
            {
                watcher.EnableRaisingEvents = false;
                watcher.Dispose();
            }
            _watchers = null;
        }

        if (_monitorTask != null)
        {
            _monitorTask.Wait(TimeSpan.FromSeconds(5));
        }

        _cancellationTokenSource.Dispose();
        Console.WriteLine("实时监控已停止");
    }

    // 处理新创建的文件
    private void ProcessNewFile(string filePath)
    {
        string fileName = Path.GetFileName(filePath);
        string extension = Path.GetExtension(filePath).ToLower();

        // 只处理特定类型的文件
        string[] validExtensions = { ".txt", ".png", ".jpg", ".jpeg", ".bmp", ".gif" };
        if (!validExtensions.Contains(extension)) return;

        // 处理 "OpenDraw" 开头的文件
        if (fileName.StartsWith("OpenDraw", StringComparison.OrdinalIgnoreCase))
        {
            try
            {
                // 定义OpenDraw.txt文件路径
                string openDrawFilePath = Path.Combine(SavePicBox, "OpenDraw.txt");

                // 检查OpenDraw.txt文件是否存在
                if (File.Exists(openDrawFilePath))
                {
                    // 读取文件中的第一行作为目标文件名
                    string targetFileName = File.ReadLines(openDrawFilePath).FirstOrDefault()?.Trim();

                    if (!string.IsNullOrEmpty(targetFileName))
                    {
                        // 构建完整的图片路径
                        string imagePath = Path.Combine(SavePicBox, targetFileName);

                        // 检查目标图片文件是否存在
                        if (File.Exists(imagePath))
                        {
                            // 使用 Windows 画图打开图片
                            Process.Start("mspaint.exe", $"\"{imagePath}\"");
                            Console.WriteLine($"已用画图打开图片: {imagePath}");

                            // 删除OpenDraw.txt文件
                            File.Delete(openDrawFilePath);
                            Console.WriteLine($"已删除OpenDraw.txt文件");
                        }
                        else
                        {
                            Console.WriteLine($"找不到对应图片: {targetFileName}");
                        }
                    }
                    else
                    {
                        Console.WriteLine("OpenDraw.txt文件为空或格式错误");
                    }
                }
                else
                {
                    Console.WriteLine($"找不到OpenDraw.txt文件: {openDrawFilePath}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"处理 OpenDraw 文件时出错: {fileName}, 错误: {ex.Message}");
            }
            return; // 处理完成后退出
        }

        else if (fileName.StartsWith("删除记录") && !fileName.StartsWith("F"))
        {
            lock (_lockObject)
            {
                _fcount++;
                string newFileName = $"F{_fcount}{fileName}";
                string newFilePath = Path.Combine(Path.GetDirectoryName(filePath), newFileName);

                try
                {
                    File.Move(filePath, newFilePath);
                    Console.WriteLine($"文件已重命名: {fileName} -> {newFileName} (Fcount={_fcount})");

                    ProcessDeleteRecordFile(newFilePath);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"重命名文件时出错: {filePath} -> {newFilePath}, 错误: {ex.Message}");
                }
            }
        }
        else if (fileName.StartsWith("C") && fileName.Length > 1) // 处理以C开头的子图片
        {
            ProcessChildScreenshot(filePath, fileName);
        }
        else if(validExtensions.Contains(extension))// 处理普通图片文件
        {
            lock (_lockObject)
            {
                ProcessNormalScreenshot(filePath, fileName);
            }
        }
    }
    // 处理普通图片文件（非特殊前缀）
    private void ProcessNormalScreenshot(string filePath, string fileName)
    {
        try
        {
            // 获取文件信息
            FileInfo fileInfo = new FileInfo(filePath);
            DateTime createTime = fileInfo.CreationTime;

            // 获取文件格式（去掉点号）
            string fileFormat = Path.GetExtension(fileName).TrimStart('.').ToLower();

            // 读取图片尺寸
            int width = 0;
            int height = 0;

            // 使用重试机制处理文件可能被锁定的情况
            int retryCount = 0;
            const int maxRetries = 3;
            bool success = false;

            while (retryCount < maxRetries && !success)
            {
                try
                {
                    using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                        using (System.Drawing.Image image = System.Drawing.Image.FromStream(stream))
                        {
                            width = image.Width;
                            height = image.Height;
                            success = true;
                        }
                    }
                }
                catch (Exception ex)
                {
                    retryCount++;
                    if (retryCount >= maxRetries)
                    {
                        Console.WriteLine($"读取图片尺寸失败: {filePath}, 错误: {ex.Message}");
                        return;
                    }
                    Thread.Sleep(500); // 等待500毫秒后重试
                }
            }

            // 检查文件是否已存在于数据库
            using (var connection = new MySqlConnection(connectionString))
            {
                connection.Open();

                // 1. 检查记录是否已存在
                string checkSql = "SELECT COUNT(*) FROM screenshots WHERE file_name = @fileName AND is_deleted = 0";
                using (var checkCmd = new MySqlCommand(checkSql, connection))
                {
                    checkCmd.Parameters.AddWithValue("@fileName", fileName);
                    long existingCount = (long)checkCmd.ExecuteScalar();

                    if (existingCount > 0)
                    {
                        Console.WriteLine($"图片已存在于数据库，跳过处理: {fileName}");
                        return;
                    }
                }

                // 2. 插入新记录（文件不存在时）
                string insertSql = @"INSERT INTO screenshots 
                        (file_name, file_path, file_format, capture_width, capture_height, create_time)
                        VALUES
                        (@fileName, @filePath, @fileFormat, @width, @height, @createTime)";

                using (var insertCmd = new MySqlCommand(insertSql, connection))
                {
                    insertCmd.Parameters.AddWithValue("@fileName", fileName);
                    insertCmd.Parameters.AddWithValue("@filePath", filePath);
                    insertCmd.Parameters.AddWithValue("@fileFormat", fileFormat);
                    insertCmd.Parameters.AddWithValue("@width", width);
                    insertCmd.Parameters.AddWithValue("@height", height);
                    insertCmd.Parameters.AddWithValue("@createTime", createTime);

                    int rowsAffected = insertCmd.ExecuteNonQuery();

                    if (rowsAffected > 0)
                    {
                        Console.WriteLine($"普通图片处理成功: {fileName}");
                    }
                    else
                    {
                        Console.WriteLine($"插入数据库失败: {fileName}");
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"处理普通图片时出错: {fileName}, 错误: {ex.Message}");
        }
    }

    private void ProcessChildScreenshot(string filePath, string fileName)
    {
        try
        {
            // 移除开头的C字符
            string parentFileNameWithExt = fileName.Substring(1);

            // 处理可能的临时文件扩展名（如.crswap）
            string parentFileName = RemoveTempExtension(parentFileNameWithExt);
            string cleanChildFileName = "C" + parentFileName;

            // 检查父图片是否存在于数据库
            using (var connection = new MySqlConnection(connectionString))
            {
                connection.Open();

                // 查询父图片信息
                string selectParentSql = "SELECT id, capture_width, capture_height FROM screenshots " +
                                        "WHERE file_name = @parentFileName AND is_deleted = 0";
                using (var selectCommand = new MySqlCommand(selectParentSql, connection))
                {
                    selectCommand.Parameters.AddWithValue("@parentFileName", parentFileName);

                    using (var reader = selectCommand.ExecuteReader())
                    {
                        if (reader.Read())
                        {
                            long parentId = reader.GetInt64("id");
                            int parentWidth = reader.GetInt32("capture_width");
                            int parentHeight = reader.GetInt32("capture_height");

                            reader.Close();

                            // 获取文件系统信息
                            FileInfo fileInfo = new FileInfo(filePath);
                            DateTime createTime = fileInfo.CreationTime;

                            // 获取纯净的文件扩展名（从处理后的文件名中）
                            string fileFormat = Path.GetExtension(cleanChildFileName).TrimStart('.');

                            // 构建纯净的文件路径（使用处理后的文件名）
                            string cleanFilePath = Path.Combine(
                                Path.GetDirectoryName(filePath),
                                cleanChildFileName
                            );

                            // 插入子图片记录（使用纯净的文件名和路径）
                            string insertChildSql = @"
INSERT INTO screenshots (file_name, file_path, file_format, capture_width, capture_height, 
                        create_time, parent_screenshot)
VALUES (@fileName, @filePath, @fileFormat, @width, @height, @createTime, @parentId)";

                            using (var insertCommand = new MySqlCommand(insertChildSql, connection))
                            {
                                insertCommand.Parameters.AddWithValue("@fileName", cleanChildFileName);
                                insertCommand.Parameters.AddWithValue("@filePath", cleanFilePath);
                                insertCommand.Parameters.AddWithValue("@fileFormat", fileFormat);
                                insertCommand.Parameters.AddWithValue("@width", parentWidth);
                                insertCommand.Parameters.AddWithValue("@height", parentHeight);
                                insertCommand.Parameters.AddWithValue("@createTime", createTime);
                                insertCommand.Parameters.AddWithValue("@parentId", parentId);

                                insertCommand.ExecuteNonQuery();

                                // 更新父图片的最后修改时间
                                string updateParentSql = "UPDATE screenshots SET last_modify_time = @modifyTime " +
                                                        "WHERE id = @id";

                                using (var updateCommand = new MySqlCommand(updateParentSql, connection))
                                {
                                    updateCommand.Parameters.AddWithValue("@modifyTime", createTime);
                                    updateCommand.Parameters.AddWithValue("@id", parentId);
                                    updateCommand.ExecuteNonQuery();
                                }

                                Console.WriteLine($"子图片处理成功: {cleanChildFileName}, 父图片ID: {parentId}");
                            }
                        }
                        else
                        {
                            Console.WriteLine($"未找到父图片: {parentFileName}，子图片: {fileName}");
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"处理子图片时出错: {fileName}, 错误: {ex.Message}");
        }
    }

    // 移除临时文件扩展名的辅助方法
    private string RemoveTempExtension(string fileName)
    {
        // 常见的临时文件扩展名列表
        string[] tempExtensions = { ".crswap", ".tmp", ".temp", ".part" };

        foreach (string ext in tempExtensions)
        {
            if (fileName.EndsWith(ext, StringComparison.OrdinalIgnoreCase))
            {
                return fileName.Substring(0, fileName.Length - ext.Length);
            }
        }

        return fileName;
    }

    private void ProcessDeleteRecordFile(string deleteRecordPath)
    {
        try
        {
            string[] fileNames = File.ReadAllLines(deleteRecordPath);

            foreach (var line in fileNames)
            {
                string targetFileName = line.Trim();
                if (string.IsNullOrEmpty(targetFileName)) continue;

                try
                {
                    // 1. 删除数据库记录
                    bool dbDeleteSuccess = DeleteRecordFromDatabase(targetFileName);
                    if (!dbDeleteSuccess)
                    {
                        Console.WriteLine($"数据库记录删除失败，跳过文件删除：{targetFileName}");
                        continue;
                    }

                    // 2. 删除本地图片文件
                    string imagePath = Path.Combine(SavePicBox, targetFileName);
                    if (File.Exists(imagePath))
                    {
                        File.Delete(imagePath);
                        Console.WriteLine($"本地图片删除成功：{imagePath}");
                    }
                    else
                    {
                        Console.WriteLine($"本地图片不存在：{imagePath}");
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"处理记录 {targetFileName} 时出错: {ex.Message}");
                }
            }
        }
        catch (IOException ex)
        {
            Console.WriteLine($"读取删除记录文件失败: {deleteRecordPath}, 错误: {ex.Message}");
        }
        catch (UnauthorizedAccessException ex)
        {
            Console.WriteLine($"无权限访问文件: {deleteRecordPath}, 错误: {ex.Message}");
        }
    }

    private bool DeleteRecordFromDatabase(string fileName)
    {
        const string sql = "DELETE FROM screenshots WHERE file_name = @FileName";

        using (var connection = new MySqlConnection(connectionString))
        {
            try
            {
                connection.Open();
                using (var command = new MySqlCommand(sql, connection))
                {
                    command.Parameters.AddWithValue("@FileName", fileName);
                    int rowsAffected = command.ExecuteNonQuery();
                    return rowsAffected > 0; // 返回是否实际删除了记录
                }
            }
            catch (MySqlException ex)
            {
                Console.WriteLine($"数据库操作失败（错误码：{ex.Number}）: {ex.Message}");
                return false;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"数据库操作异常: {ex.Message}");
                return false;
            }
        }
    }
}
